#include "Irp.h"

NTSTATUS IrpGeneral(IN struct _DEVICE_OBJECT* DeviceObject, IN OUT struct _IRP* Irp)
{
    PDEVICE_EXTENSION lpDeviceExtension = (PDEVICE_EXTENSION)(DeviceObject->DeviceExtension);
    NTSTATUS retStatus = STATUS_SUCCESS;

    switch (lpDeviceExtension->DeviceType)
    {
    case CONTROL:
    {
        Irp->IoStatus.Status = STATUS_SUCCESS;
        Irp->IoStatus.Information = 0;
        IoCompleteRequest(Irp, IO_NO_INCREMENT);
        break;
    }
    case FILTER:
    {
        IoSkipCurrentIrpStackLocation(Irp);
        retStatus = IoCallDriver(lpDeviceExtension->AttachedToDeviceObject, Irp);
        break;
    }
    default:
        break;
    }

    return retStatus;
}

NTSTATUS IrpDeviceControl(IN struct _DEVICE_OBJECT* DeviceObject, IN OUT struct _IRP* Irp)
{
    PDEVICE_EXTENSION lpDeviceExtension = (PDEVICE_EXTENSION)DeviceObject->DeviceExtension;
    PIO_STACK_LOCATION lpIoStackLocation = IoGetCurrentIrpStackLocation(Irp);
    NTSTATUS retStatus = STATUS_SUCCESS;
    UNREFERENCED_PARAMETER(lpIoStackLocation);

    switch (lpDeviceExtension->DeviceType)
    {
    case CONTROL:
    {
        Irp->IoStatus.Status = STATUS_SUCCESS;
        Irp->IoStatus.Information = 0;
        IoCompleteRequest(Irp, IO_NO_INCREMENT);
        break;
    }
    case FILTER:
    {
        IoSkipCurrentIrpStackLocation(Irp);
        retStatus = IoCallDriver(lpDeviceExtension->AttachedToDeviceObject, Irp);
        break;
    }
    default:
        break;
    }

    return retStatus;
}

NTSTATUS IrpWrite(IN struct _DEVICE_OBJECT* DeviceObject, IN OUT struct _IRP* Irp)
{
    NTSTATUS retStatus = STATUS_SUCCESS;
    PDEVICE_EXTENSION lpDeviceExtension = (PDEVICE_EXTENSION)(DeviceObject->DeviceExtension);
    PCHAR lpBuff = NULL;

    switch (lpDeviceExtension->DeviceType)
    {
    case CONTROL:
    {
        Irp->IoStatus.Status = STATUS_SUCCESS;
        Irp->IoStatus.Information = 0;
        IoCompleteRequest(Irp, IO_NO_INCREMENT);
        break;
    }
    case FILTER:
    {
        if (Irp->MdlAddress)
            lpBuff = (PCHAR)MmGetSystemAddressForMdlSafe(Irp->MdlAddress, NormalPagePriority);
        else if (Irp->AssociatedIrp.SystemBuffer)
            lpBuff = (PCHAR)Irp->AssociatedIrp.SystemBuffer;
        else
            lpBuff = (PCHAR)Irp->UserBuffer;

        if (lpBuff)
            DBGPRINT("%s\r\n", lpBuff);

        IoSkipCurrentIrpStackLocation(Irp);
        retStatus = IoCallDriver(lpDeviceExtension->AttachedToDeviceObject, Irp);
        break;
    }
    default:
        break;
    }

    return retStatus;
}
